﻿using System.Linq.Dynamic.Core;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Auditing;

namespace VI.Abp
{
    public static class QueryableExtensions
    {
        #region 查询排序
        /// <summary>
        /// 查询排序
        /// </summary>
        /// <param name="query">查询</param>
        /// <param name="input">分页请求</param>
        public static IQueryable<TEntity> ApplySorting<TEntity>(this IQueryable<TEntity> query, IPagedAndSortedResultRequest input)
        {
            //按自定义排序
            if (input is ISortedResultRequest sortInput)
            {
                if (!sortInput.Sorting.IsNullOrWhiteSpace())
                {
                    return query.OrderBy(sortInput.Sorting);
                }
            }

            //按创建时间排序
            // if (input is ILimitedResultRequest)
            // {
            //     return ApplyDefaultSorting(query);
            // }

            //无排序结果
            return query;
        }

        /// <summary>
        /// 默认排序
        /// </summary>
        /// <param name="query">The query.</param>
        private static IQueryable<TEntity> ApplyDefaultSorting<TEntity>(IQueryable<TEntity> query)
        {
            if (typeof(TEntity).IsAssignableTo<IHasCreationTime>())
            {
                return query.OrderByDescending(e => ((IHasCreationTime)e).CreationTime);
            }

            throw new AbpException("No sorting specified but this query requires sorting. Override the ApplyDefaultSorting method for your application service derived from AbstractKeyReadOnlyAppService!");
        }

        #endregion

        #region 分页
        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="query">The query.</param>
        /// <param name="input">The input.</param>
        public static IQueryable<TEntity> ApplyPaging<TEntity>(this IQueryable<TEntity> query, IPagedResultRequest input)
        {
            //Try to use paging if available
            if (input is IPagedResultRequest pagedInput)
            {
                return query.PageBy(pagedInput);
            }
            //Try to limit query result if available
            if (input is ILimitedResultRequest limitedInput)
            {
                return query.Take(limitedInput.MaxResultCount);
            }
            //No paging
            return query;
        }

        #endregion
    }
}